package com.it.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.it.reggie.commen.R;
import com.it.reggie.entity.Category;
import com.it.reggie.entity.Dish;
import com.it.reggie.entity.DishDto;
import com.it.reggie.entity.DishFlavor;
import com.it.reggie.service.CategoryService;
import com.it.reggie.service.DishFlavorService;
import com.it.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;


import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/dish")
@SuppressWarnings(value = "all")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisTemplate redisTemplate;

    //添加菜品
    @PostMapping
    //**************
    //将数据存储到缓存里，value表示缓存的名称，每个缓存下面可以有多个key
    // key:缓存的key
    // key = "#result.id"表示返回值对象里的id,也可以改成dishDto.id
 //   @CachePut(value = "dishDtoCache",key = "#result.id")
    public R addDish(@RequestBody DishDto dishDto) {

        //存储菜品信息
        dishService.save(dishDto);

        Long id = dishDto.getId();


        List<DishFlavor> flavors = dishDto.getFlavors();

        if (flavors != null) {
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(id);
                dishFlavorService.save(flavor);
            }
        }

        //存储菜品成功后删除redis中对应的菜品数据
        redisTemplate.delete("dish_"+dishDto.getCategoryId());

        return R.success("添加成功");

    }

    //分页查询菜品数据
    @GetMapping("/page")
    private R selectByPage(Integer page, Integer pageSize, String name) {

        List<DishDto> dtoList = new ArrayList<>();

        //分页查询
        IPage<Dish> iPage = new Page<>(page, pageSize);

        //创建查询条件对象
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();

        qw.like(name != null, Dish::getName, name);

        dishService.page(iPage, qw);

        //获取总条数
        long total = iPage.getTotal();

        //获取所有的菜品数据
        List<Dish> dishList = iPage.getRecords();

        //遍历dishList集合
        for (Dish dish : dishList) {

            //获取每一个dish中的CategoryId
            Long categoryId = dish.getCategoryId();
            Category category = categoryService.getById(categoryId);

            DishDto dishDto = new DishDto();
            //相同则添加categoryName到dishDato中
            dishDto.setCategoryName(category.getName());
            //将dish中的数据拷贝到dishDto中
            BeanUtils.copyProperties(dish, dishDto);
            //添加dishDto到集合中
            dtoList.add(dishDto);

        }
        //创建map集合用于响应数据，键要和前端的响应数据一致
        Map map = new HashMap();

        map.put("total", total);
        map.put("records", dtoList);

        return R.success(map);

    }

    //根据id查询菜品数据，用于回显
    @GetMapping("/{id}")
    public R selectById(@PathVariable Long id) {

        DishDto dishDto = new DishDto();

        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();

        qw.eq(id != null, Dish::getId, id);

        //查询菜品信息
        Dish dish = dishService.getOne(qw);

        Long categoryId = dish.getCategoryId();

        //将菜品数据复制到dishDto
        BeanUtils.copyProperties(dish, dishDto);

        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(DishFlavor::getDishId, id);

        //查询菜品口味信息
        List<DishFlavor> list = dishFlavorService.list(queryWrapper);

        //添加到dishDto
        dishDto.setFlavors(list);

        LambdaQueryWrapper<Category> qw2 = new LambdaQueryWrapper<>();

        qw2.eq(Category::getId, categoryId);

        //查询菜品分类信息
        Category categoryServiceOne = categoryService.getOne(qw2);

        String name = categoryServiceOne.getName();

        dishDto.setCategoryName(name);

        return R.success(dishDto);

    }

    //修改菜品
    @PutMapping
    public R upDateById(@RequestBody DishDto dishDto) {

        Long id = dishDto.getId();

        LambdaQueryWrapper<Dish> qw1 = new LambdaQueryWrapper<>();

        qw1.eq(Dish::getId, id);

        //修改菜品信息
        dishService.update(dishDto, qw1);

        Long categoryId = dishDto.getCategoryId();
        String categoryName = dishDto.getCategoryName();
        Category category = new Category();
        category.setName(categoryName);

        LambdaQueryWrapper<Category> qw2 = new LambdaQueryWrapper<>();
        qw2.eq(Category::getId, categoryId);
        //修改菜品分类名称
        categoryService.update(category, qw2);

        //获取口味数据,删除原本的所有口味数据
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, id);
        List<DishFlavor> list = dishFlavorService.list(queryWrapper);
        List<Long> longs = list.stream().map(DishFlavor::getId).collect(Collectors.toList());
        dishFlavorService.removeByIds(longs);

        List<DishFlavor> flavors = dishDto.getFlavors();

        //添加菜品口味
        for (DishFlavor flavor : flavors) {

            flavor.setDishId(id);

            dishFlavorService.save(flavor);

        }

        //清理某个分类下面的菜品数据
//        Long categoryId1 = dishDto.getCategoryId();
//        redisTemplate.delete(categoryId1);

        //获取所有的Key
        Set keys = redisTemplate.keys("dish_*");
        //清理所有的菜品数据
        redisTemplate.delete(keys);

        return R.success("修改成功");
    }


    //删除菜品
//    @CacheEvict(value = "dishDtoCache",key = "#root.args[0]")//清除指定缓存
    /*
    * **************
      清除指定缓存，value表示缓存的名称，每个缓存下面可以有多个key
      key:缓存的key
      * key="root.p0"
      * key="#ids"
    * */
    @DeleteMapping
    public R delete(@RequestParam List<Long> ids) {

        dishService.removeByIds(ids);

//      dishFlavorService.removeByIds(ids);

        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.in(DishFlavor::getDishId,ids);

        dishFlavorService.removeByIds(ids);


        //获取所有以dish_开头的key
        Set keys = redisTemplate.keys("dish_*");
        //清空所有分类下的菜品缓存
        redisTemplate.delete(keys);

        return R.success("删除成功");

    }


    //起售，停售
    @PostMapping("/status/{status}")
    public R upDateStatus(@PathVariable Integer status, @RequestParam List<Long> ids) {

        dishService.upDateStatus(status, ids);

        return R.success("修改成功");

    }

    //根据分类id查询该分类下的所有菜品集合
    //现在redis缓存里查数据，有直接返回，没有则在数据库里查询然后将数据添加到缓存
    @GetMapping("/list")

    public R selectByCategoryId(Long categoryId,Integer status) {

        ValueOperations valueOperations = redisTemplate.opsForValue();

        //创建Key
        String key = "dish_"+categoryId;

        List<DishDto> dtoListRedis = (List<DishDto>) valueOperations.get(key);

        if (dtoListRedis!=null){

            return R.success(dtoListRedis);

        }


        //创建dish条件构造器
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();

        qw.eq(Dish::getCategoryId, categoryId);

        qw.eq(status!=null,Dish::getStatus, status);

        //获取所有的dish数据
        List<Dish> dishList = dishService.list(qw);

        //创建dishdto集合
        List<DishDto> dtoList = new ArrayList<>();


        for (Dish dish : dishList) {
            DishDto dishDto = new DishDto();
            Long id = dish.getId();
            LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DishFlavor::getDishId, id);
            List<DishFlavor> list = dishFlavorService.list(queryWrapper);
            BeanUtils.copyProperties(dish, dishDto);
            dishDto.setFlavors(list);
            dtoList.add(dishDto);
        }

        redisTemplate.opsForValue().set(key, dishList, 60, TimeUnit.MINUTES);

        return R.success(dtoList);
    }
}
